package client.gui;

/**
 * GameRenderer
 */

import boardtiles.*;
import java.awt.*;
import java.awt.image.*;
import misc.*;
import activepieces.*;
import java.util.*;

public class GameRenderer {

    private static Image renderedTileMap;
    private static final int TOP = 0;
    private static final int BOTTOM = 1;
    private static final int TOP_RIGHT = 2;
    private static final int BOTTOM_RIGHT = 3;
    private static final int BOTTOM_LEFT = 4;
    private static final int TOP_LEFT = 5;

    private static final int UP = 0;
    private static final int DOWN = 1;
    private static final int LEFT = 2;
    private static final int RIGHT = 3;

    /**
     * Draws the board. For purposes of deciding which neighbors are left,
     * right, top, bottom etc. it uses the constants defined in this class
     * @param boardRoot
     * @param players
     * @param environmentalPieces
     * @param width final width of the renderered board image
     * @param height final height of the rendered board image
     * @return
     */
    public static Image drawBoard(Tile boardRoot,
                                  Player[] players,
                                  EnvironmentalPiece[] environmentalPieces,
                                  int width,
                                  int height) {
        //calculate the bounds in "board space"
            //height and width will be measured in units of tile


        return null;
    }
    
    private static Dimension calculateBounds(Tile boardRoot) {
        double highBound = findFarthest(boardRoot, 0, UP);
        double lowBound = findFarthest(boardRoot, 0, DOWN);
        double rightBound = findFarthest(boardRoot, 0, RIGHT);
        double leftBound = findFarthest(boardRoot, 0, LEFT);
        int width = (int)Math.ceil(rightBound + leftBound);
        int height = (int)Math.ceil(highBound + lowBound);
        return new Dimension(width, height);
    }


    private static double findFarthest(Tile tile,
            double currentValue, int direction) {
        if (tile == null) {
            return currentValue;
        }
        else {
            double maxValue = Double.NEGATIVE_INFINITY;
            Tile[] neighbors = tile.getNeighbors();
            for (int i = 0; i < neighbors.length; i++) {
                double modifier = calculateModifier(i, direction);
                double neighborValue = findFarthest(neighbors[i],
                        currentValue + modifier, direction);
                if (neighborValue > maxValue) {
                    maxValue = neighborValue;
                }
            }
            return maxValue;
        }
    }

    private static double calculateModifier(int tileDirection, int searchDirection) {
        switch (tileDirection) {
            case TOP:
                switch (searchDirection) {
                    case UP:
                        return 1;
                    case DOWN:
                        return -1;
                    case LEFT:
                        return 0;
                    case RIGHT:
                        return 0;
                }
            case BOTTOM:
                switch (searchDirection) {
                    case UP:
                        return -1;
                    case DOWN:
                        return 1;
                    case LEFT:
                        return 0;
                    case RIGHT:
                        return 0;
                }
            case BOTTOM_LEFT:
                switch (searchDirection) {
                    case UP:
                        return -Math.sin(Math.PI/3);
                    case DOWN:
                        return Math.sin(Math.PI/3);
                    case LEFT:
                        return .5;
                    case RIGHT:
                        return -.5;
                }
            case BOTTOM_RIGHT:
                switch (searchDirection) {
                    case UP:
                        return -Math.sin(Math.PI/3);
                    case DOWN:
                        return Math.sin(Math.PI/3);
                    case LEFT:
                        return -.5;
                    case RIGHT:
                        return .5;
                }
            case TOP_LEFT:
                switch (searchDirection) {
                    case UP:
                        return Math.sin(Math.PI/3);
                    case DOWN:
                        return -Math.sin(Math.PI/3);
                    case LEFT:
                        return .5;
                    case RIGHT:
                        return -.5;
                }
            case TOP_RIGHT:
                switch (searchDirection) {
                    case UP:
                        return Math.sin(Math.PI/3);
                    case DOWN:
                        return -Math.sin(Math.PI/3);
                    case LEFT:
                        return -.5;
                    case RIGHT:
                        return .5;
                }
        }
        //should never get here if function called properly
        return 0;
    }
    
    

    public static Image drawHexagon(int length) {
        Image image = new BufferedImage(2 * length, 2 * length, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = (Graphics2D)image.getGraphics();
        int xPoints[] = new int[6];
        int yPoints[] = new int[6];

        int xCenter = length;
        int yCenter = length;

        for (int i = 0; i < 6; i++) {
            double angle = (Math.PI / 3) * i;
            xPoints[i] = xCenter + (int)Math.round((length * Math.cos(angle)));
            yPoints[i] = yCenter + (int)Math.round((length * Math.sin(angle)));
        }
        g.setColor(Color.black);
        g.fillRect(0, 0, length * 2, length * 2);
        g.setColor(Color.red);
        g.fillPolygon(xPoints, yPoints, 6);
        return image;
    }

    private class TileWrapper {
        Tile tile;
        int x, y;

        public TileWrapper(Tile tile, int x, int y) {
            this.tile = tile;
            this.x = x;
            this.y = y;
        }
    }
}